//
// DashboardService.cs
//
// Copyright (C) 2008 Lukas Lipka <lukaslipka@gmail.com>
//

using System;
using System.Runtime.InteropServices;

using Dashboard;

using Banshee.ServiceStack;
using Banshee.MediaEngine;
using Banshee.Collection;
using Banshee.Gui;

namespace Banshee.Dashboard
{
	public class DashboardService : IExtensionService
	{
		private Connection connection = null;
		private string clue_message_id = null;

		public DashboardService ()
		{
		}
        
		void IExtensionService.Initialize ()
		{
			ServiceManager.PlayerEngine.EventChanged += OnPlayerEngineEventChanged;
		}

		private void OnPlayerEngineEventChanged (object o, PlayerEngineEventArgs args)
		{
			if (args.Event != PlayerEngineEvent.StartOfStream)
				return;

			// FIXME: Our client API sucks at handling cases when dashboard
			// is not running and thats the reason the following block of code
			// is in a try block.

			try {
				if (connection == null)
					connection = Connection.Create ();
				
				TrackInfo track = ServiceManager.PlayerEngine.CurrentTrack;
				
				// FIXME: The window Xid detection sucks, we might consider
				// adding this into our client API.
				
				ClueMessage clue_message = new ClueMessage ();
				clue_message.Path = "/event/media/playing";
				
				GtkElementsService elements_service = ServiceManager.Get<GtkElementsService> ("GtkElementsService");
				clue_message.Window = (ulong) gdk_x11_drawable_get_xid (elements_service.PrimaryWindow.GdkWindow.Handle);
				
				Clue track_clue = new Clue ("db:media");
				
				track_clue.Properties.Add (new Property ("dc:title", "dc:string", track.TrackTitle));
				track_clue.Properties.Add (new Property ("dc:extent", "dc:timespan", track.Duration.ToString ()));
				
				if (!String.IsNullOrEmpty (track.ArtistName))
					track_clue.Properties.Add (new Property ("db:artist", "dc:string", track.ArtistName));
				
				if (!String.IsNullOrEmpty (track.AlbumTitle))
					track_clue.Properties.Add (new Property ("db:album", "dc:string", track.AlbumTitle));
				
				if (!String.IsNullOrEmpty (track.MimeType))
					track_clue.Properties.Add (new Property ("dc:format", "dc:string", track.MimeType));
				
				//if (!String.IsNullOrEmpty (track.CoverArtFileName))
				//	track_clue.Properties.Add (new Property ("dc:image", "dc:uri", String.Format ("file://{0}", track.CoverArtFileName)));
				
				clue_message.Clues.Add (track_clue);
				
				if (!String.IsNullOrEmpty (clue_message_id))
					clue_message.Replaces = clue_message_id;
				
				clue_message_id = clue_message.Id;
				
				connection.Send (clue_message);
			} catch (Exception e) {
				Console.WriteLine ("Dashboard plugin - Failed to send clue:");
				Console.WriteLine (e);
			}
		}
        
		string IService.ServiceName {
			get { return "DashboardService"; }
		}

		[DllImport("libgdk-x11-2.0.so")]
		extern static UIntPtr gdk_x11_drawable_get_xid (IntPtr window);
	}
}
